
package com.kugou.game.sdk.ui.activity;

import com.kugou.download.DownloadFile;
import com.kugou.download.FileDownloader;
import com.kugou.download.IProgressListener;
import com.kugou.download.manager.ParamsWrapper;
import com.kugou.framework.base.LogUtil;
import com.kugou.framework.v4.ViewCompat;
import com.kugou.game.sdk.base.BaseCommonTitleFragmentActivity;
import com.kugou.game.sdk.core.SDKActions;
import com.kugou.game.sdk.core.SDKControler;
import com.kugou.game.sdk.download.DownloadServiceUtil;
import com.kugou.game.sdk.statistics.StaticsManager;
import com.kugou.game.sdk.ui.widget.TipsLayout;
import com.kugou.game.sdk.utils.AndroidMethodProvider;
import com.kugou.game.sdk.utils.AppUtil;
import com.kugou.game.sdk.utils.DownloadHelper;
import com.kugou.game.sdk.utils.NetWorkUtil;
import com.kugou.game.sdk.utils.NetWorkUtil.NetworkType;
import com.kugou.game.sdk.utils.Rx;

import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;

import java.util.ArrayList;

/**
 * 描述:H5游戏中心页面
 * 
 * @author liux
 * @since 2014-10-29 下午04:34:03
 */
@SuppressLint({
        "HandlerLeak", "SetJavaScriptEnabled"
})
public class GameCenterActivity extends BaseCommonTitleFragmentActivity {

    public static final String SOURCE_KEY = "source";

    private WebView mWeb;

    private FrameLayout mLayout;

    private TipsLayout mTipsLayout;

    private View mTitleBackBtn, mLoadingLayout;

    private WebSettings mSet;

    private static final String TAG = "AndroidMethodProvider";

    public static final String URL_KEY = "url";

    private boolean mIsDestroy;

    private String mSource = "";

    private AndroidMethodProvider mProvider;

    /** 游戏中心1.0主页正式地址 */
    public static final String MAIN_PAGE_URL_BASE = "http://center.game.kugou.com/m/";

    public static final String MAIN_PAGE_URL = MAIN_PAGE_URL_BASE + "?plat=5&imei="
            + AppUtil.getMachineSN(SDKControler.getContext()) + "&mid="
            + AppUtil.getKugouMID(SDKControler.getContext()) + "&uuid="
            + AppUtil.getKugouUUID(SDKControler.getContext()) + "&channelid="
            + SDKControler.getChannelId();

    /** 游戏中心2.0主页正式地址 */
    // public static final String MAIN_PAGE_URL_BASE =
    // "http://center.game.kugou.com/v2/m/";
    //
    // public static final String MAIN_PAGE_URL = MAIN_PAGE_URL_BASE +
    // "?plat=5&imei="
    // + AppUtil.getMachineSN(SDKControler.getContext()) + "&mid="
    // + AppUtil.getKugouMID(SDKControler.getContext()) + "&uuid="
    // + AppUtil.getKugouUUID(SDKControler.getContext()) + "&channelid="
    // + SDKControler.getChannelId();

    private String url = "";

    /** 加载页面是否出错 */
    private boolean mLoadPageError = false;

    /** 错误页面是否正在显示 */
    private boolean mShowingErrorTipPage = false;

    private boolean mIsHomePage = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initState();
        url = getIntent().getStringExtra(URL_KEY);
        if (TextUtils.isEmpty(url)) {
            mIsHomePage = true;
            url = MAIN_PAGE_URL;
            // 发送游戏中心DAU统计
            StaticsManager.sendGameCenterDauStatics(GameCenterActivity.this);
        }
        setContentView(Rx.layout.kg_activity_gamecenter);
        initView();
        loadData();
    }

    private void initState() {
        if (SDKControler.isInitialize()) {
            // 是否全屏
            if (SDKControler.isFullScreen()) {
                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                        WindowManager.LayoutParams.FLAG_FULLSCREEN);
            }
            // 设置为竖屏
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setTheme(Rx.style.kg_MyActivity);

            // 添加下载监听回调
            DownloadServiceUtil.addListener(mProgressListener);

        } else {
            throw new RuntimeException("AppCenter还没有初始化.");
        }
    }

    // Tip:WebView 的setVisibility方法，某些机型，如摩托罗拉me865
    // 4.0.0系统设置从View.GONE转变为View.VISIBLE时WebView不能正常显示。
    @SuppressLint("NewApi")
    private void initView() {
        mLayout = (FrameLayout) findViewById(Rx.id.kg_gamecenter_layout);
        mWeb = (WebView) findViewById(Rx.id.kg_gamecenter_web);
        mWeb.setHorizontalScrollBarEnabled(false);
        mWeb.setBackgroundColor(0);
        // 设置View.LAYER_TYPE_SOFTWARE，不过可能会导致页面的图片切换时会文字跳动，但不设置可能会影响webview的渲染，造成页面内存过大
        // 低配机型不支持代码设置
        // mWeb.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        // 2.3系统，有滚动条时，右侧会出现白边
        if (Build.VERSION.SDK_INT <= 10) {
            mWeb.setVerticalScrollBarEnabled(false);
        }

        mLoadingLayout = findViewById(Rx.id.kg_gamecenter_loading_layout);
        mTitleBackBtn = findViewById(Rx.id.kg_common_btn_back);
        mTitleBackBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!GameCenterActivity.this.isFinishing()) {
                    finish();
                }
            }
        });

        mTipsLayout = (TipsLayout) findViewById(Rx.id.kg_tips_layout);
        mTipsLayout.setLoadingText("");
        mTipsLayout.setLoadingViewBackground(Rx.drawable.kg_gamecenter_loading);

        mSet = mWeb.getSettings();
        mSet.setJavaScriptEnabled(true);

        // 设置默认编码
        mSet.setDefaultTextEncodingName("utf-8");
        // 设置自适应屏幕
        mSet.setUseWideViewPort(true);
        mSet.setLoadWithOverviewMode(true);
        // 设置屏幕单列显示，不可左右拖动(<--慎用，可能会导致网页css失效-->)
        // mSet.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

        mSet.setSupportZoom(false);
        mSet.setBuiltInZoomControls(false);
        // 设置local storage
        mSet.setDomStorageEnabled(true);

        // mSet.setRenderPriority(RenderPriority.HIGH);

        try {
            // 设置H5缓存可用
            mSet.setAppCacheEnabled(true);
            String appCachePath = getApplication().getDir("cache", MODE_PRIVATE).getAbsolutePath();
            mSet.setAppCachePath(appCachePath);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            // 应用开启数据库缓存
            mSet.setDatabaseEnabled(true);
            String appDatabasePath = getApplicationContext().getDir("database",
                    Context.MODE_PRIVATE).getAbsolutePath();
            mSet.setDatabasePath(appDatabasePath);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // WebView先不要自动加载图片，等页面finish后再发起图片加载
        if (Build.VERSION.SDK_INT >= 19) {
            mSet.setLoadsImagesAutomatically(true);
        } else {
            mSet.setLoadsImagesAutomatically(false);
        }

        // 设置缓存策略
        if (!NetWorkUtil.isNetworkAvailable(GameCenterActivity.this)) {
            mSet.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        } else {
            // mWeb.clearCache(true);
            mSet.setCacheMode(WebSettings.LOAD_DEFAULT);
        }
        // 添加useragent
        String oldUserAgent = mSet.getUserAgentString();
        String sdkVersion = SDKControler.getSDKVersionName();
        mSet.setUserAgentString(oldUserAgent + " KGMobileSDK/" + sdkVersion);

        mProvider = new AndroidMethodProvider(GameCenterActivity.this, mWeb);
        mWeb.addJavascriptInterface(mProvider, "android");
        mWeb.setWebViewClient(new CustomWebViewClient());
        mWeb.setWebChromeClient(new CustomWebChromeClient());

        // 配置硬件加速
        try {
            ViewCompat.setLayerType(mWeb, ViewCompat.LAYER_TYPE_NONE, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // LogUtil.d(TAG, "硬件加速：" + mWeb.isHardwareAccelerated());

    }

    /**
     * 加载数据
     */
    private void loadData() {
        // 重置标识
        mLoadPageError = false;
        mShowingErrorTipPage = false;

        // 显示加载提示界面
        mLoadingLayout.setVisibility(View.VISIBLE);
        mTipsLayout.show(TipsLayout.TYPE_LOADING);

        // 加载网页
        LogUtil.d(TAG, "url-->" + url);
        mWeb.loadUrl(url);
    }

    private static final int MSG_BACK_CONTINUE_ABNORMAL_DOWNLOAD_TASK = 1;

    private static final int MSG_UI_SHOW_PAGE = 2;

    @Override
    public void handleBackgroundMessage(Message msg) {
        switch (msg.what) {
            case MSG_BACK_CONTINUE_ABNORMAL_DOWNLOAD_TASK:
                continueAbnormalPauseDownloadTasks();
                break;
        }
    }

    @Override
    public void handleUiMessage(Message msg) {
        switch (msg.what) {
            case MSG_UI_SHOW_PAGE:
                showPage();
                break;
        }
    }

    private void showPage() {
        if (!mLoadPageError) {
            mLoadingLayout.setVisibility(View.GONE);
        } else {
            showLoadFailLayout();
        }
    }

    public void showPageAfterStartLoadPage() {
        sendEmptyUiMessageDelayed(MSG_UI_SHOW_PAGE, 200);
    }

    /**
     * 显示加载失败提示页面
     */
    @SuppressLint("NewApi")
    private void showLoadFailLayout() {
        if (!mShowingErrorTipPage) {
            View view = LayoutInflater.from(this).inflate(Rx.layout.kg_layout_load_faile_two, null);
            view.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    loadData();
                }
            });

            // 加载一个友好空白界面，替换出错信息页面
            mWeb.loadData("<html><p></p></html>", "text/html", "utf-8");
            mLoadingLayout.setVisibility(View.VISIBLE);
            mTipsLayout.setCustomView(view);
            mTipsLayout.show(TipsLayout.TYPE_CUSTOM_VIEW);

            mShowingErrorTipPage = true;
        }
    }

    /** 处理请求和响应 */
    class CustomWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            LogUtil.d(TAG, "shouldOverrideUrlLoading()--->" + url);
            view.loadUrl(url);
            return true;
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description,
                String failingUrl) {
            LogUtil.d(TAG, "onReceivedError()---->" + errorCode);
            mLoadPageError = true;
        }

        @SuppressLint("NewApi")
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            // LogUtil.d(TAG, "onPageStarted()---开始加载页面");
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            // LogUtil.d(TAG, "onPageFinished()---加载页面结束");
            if (!mSet.getLoadsImagesAutomatically()) {
                mSet.setLoadsImagesAutomatically(true);
            }

            showPage();

            // 只在进入首页时检测自动下载
            if (mIsHomePage) {
                if (NetWorkUtil.isNetworkAvailable(GameCenterActivity.this)
                        && NetWorkUtil.getNetworkType(GameCenterActivity.this).equals(
                                NetworkType.WIFI)) {
                    sendEmptyBackgroundMessage(MSG_BACK_CONTINUE_ABNORMAL_DOWNLOAD_TASK);
                }
            }
            super.onPageFinished(view, url);
        }

    }

    /** 处理与JS的交互 */
    class CustomWebChromeClient extends WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            // LogUtil.d(TAG, "onProgressChanged()--->" + newProgress);
        }

        // 常用出错提示语
        String[] errorTips = {
                "404", "NOT FOUND", "ERROR PAGE", "400", "403", "408", "500", "501", "502", "503"
        };

        @SuppressLint("DefaultLocale")
        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
            if (!TextUtils.isEmpty(title)) {
                String upperTitle = title.toUpperCase();
                LogUtil.d(TAG, "onReceivedTitle()--->" + upperTitle);
                for (String error : errorTips) {
                    if (upperTitle.contains(error)) {
                        mLoadPageError = true;
                        showLoadFailLayout();
                        return;
                    }
                }
            }
        }
    }

    private IProgressListener mProgressListener = new IProgressListener() {

        @Override
        public void onProgressChanged(DownloadFile file, int state) {
            Message msg = mProgressHandler.obtainMessage();
            msg.what = MSG_PROGRESS_CHANGED;
            msg.obj = file;
            msg.arg1 = state;
            mProgressHandler.sendMessage(msg);
        }

        @Override
        public void onError(DownloadFile file, int errorType) {
            Message msg = mProgressHandler.obtainMessage();
            msg.what = MSG_ERROR;
            msg.obj = file;
            msg.arg1 = errorType;
            mProgressHandler.sendMessage(msg);
        }

    };

    private static final int MSG_PROGRESS_CHANGED = 1;

    private static final int MSG_ERROR = 2;

    private Handler mProgressHandler = new Handler() {

        public void handleMessage(Message msg) {
            if (msg.obj == null || !(msg.obj instanceof DownloadFile)) {
                return;
            }
            DownloadFile file = (DownloadFile) msg.obj;
            switch (msg.what) {
                case MSG_PROGRESS_CHANGED:
                    int state = msg.arg1;
                    onProgressChanged(file, state);
                    break;
                case MSG_ERROR:
                    int errorType = msg.arg1;
                    onError(file, errorType);
                    break;
            }
        };
    };

    /**
     * 下载进度改变回调
     * 
     * @param file
     * @param state
     */
    private void onProgressChanged(DownloadFile file, int state) {
        try {
            LogUtil.d(TAG, "onProgressChanged()--->" + state);

            if (file != null) {
                // 下载状态码，默认为0，未下载状态。
                int downloadState = 0;

                if (state == FileDownloader.DOWNLOADING) {// 正在下载
                    downloadState = 3;
                } else if (DownloadServiceUtil.isInWaittingQueue(file.getKey())) {// 等待下载队列中
                    downloadState = 4;
                } else if (state == FileDownloader.INTERUPT) {// 暂停
                    downloadState = 5;
                } else if (state == FileDownloader.FINISH) {// 下载完成
                    downloadState = 7;
                }

                JSONObject obj = new JSONObject();
                obj.put("filehash", file.getKey());
                obj.put("filesize", file.getFileSize());
                obj.put("readsize", file.getHaveRead());
                obj.put("lefttime", getDownloadLeftTime(file));
                obj.put("progress", DownloadHelper.getDownloadingProgress(file));
                obj.put("speed", file.getStatis().getCurrentSpeed());
                obj.put("state", downloadState);

                String json = obj.toString().replace("\\", "");
                mWeb.loadUrl("javascript:progressChangeCallBack('" + json + "')");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String getDownloadLeftTime(DownloadFile file) {
        // 速度，单位：kb/s
        int speed = file.getStatis().getCurrentSpeed();
        // 剩余大小，单位：kb
        long leftsize = (file.getFileSize() - file.getHaveRead()) / 1024;
        if (speed == 0) {
            return "";
        }
        // 剩余时间，单位：s
        long time = leftsize / speed;
        return AppUtil.formatLongToTimeStr(time * 1000);
    }

    /**
     * 下载出现异常回调
     * 
     * @param file
     * @param errorType
     */
    private void onError(DownloadFile file, int errorType) {
        LogUtil.d(TAG, "onError()--->" + errorType);
        if (file != null) {
            String filehash = file.getKey();
            mWeb.loadUrl("javascript: downloadErrorCallBack ('" + filehash + "')");
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mIsDestroy = true;
        try {
            DownloadServiceUtil.removeListener(mProgressListener);

            mLayout.removeAllViews();
            mWeb.stopLoading();
            mWeb.removeAllViews();
            mWeb.destroy();
            mWeb = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onBackPressed() {
        if (mWeb.canGoBack() && !mLoadPageError) {
            mWeb.goBack();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public void setupActions(ArrayList<String> actions) {
        actions.add(SDKActions.ACTION_APP_INSTALL);
        actions.add(SDKActions.ACTION_APP_REMOVE);
        actions.add(SDKActions.ACTION_DOWNLOAD_STATE_CHANGED);
        actions.add(SDKActions.ACTION_INSTALL_STATE_CHANGED);
        actions.add(SDKActions.ACTION_DELETE_DOWNLOADFILE);
        actions.add(SDKActions.ACTION_CLOSE_GAME_CENTER);
        actions.add(ConnectivityManager.CONNECTIVITY_ACTION);
        actions.add(SDKActions.ACTION_LOGIN_SUCCESS);
        actions.add(SDKActions.ACTION_REGISTER_SUCCESS);
    }

    @Override
    public void handleBroadcast(Context context, Intent intent) {
        String action = intent.getAction();
        if (SDKActions.ACTION_APP_INSTALL.equals(action)) {// 安装游戏
            String pakageName = intent.getStringExtra("packageName");
            LogUtil.d(TAG, "onReceive()---安装游戏回调->" + pakageName);

            mWeb.loadUrl("javascript:installAppCallBack('" + pakageName + "')");
        } else if (SDKActions.ACTION_APP_REMOVE.equals(action)) {// 卸载游戏
            String pakageName = intent.getStringExtra("packageName");
            LogUtil.d(TAG, "onReceive()---卸载游戏回调->" + pakageName);

            mWeb.loadUrl("javascript:uninstallAppCallBack('" + pakageName + "')");

        } else if (SDKActions.ACTION_DELETE_DOWNLOADFILE.equals(action)) {// 删除游戏
            String key = intent.getStringExtra("downloadfile_key");

            LogUtil.d(TAG, "onReceive()---删除下载回调->" + key);
            mWeb.loadUrl("javascript:deleteDownloadCallBack('" + key + "')");

        } else if (SDKActions.ACTION_CLOSE_GAME_CENTER.equals(action)) {// 关闭游戏中心
            GameCenterActivity.this.finish();
        } else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {// 网络状态切换
            if (NetWorkUtil.isNetworkAvailable(GameCenterActivity.this)
                    && NetWorkUtil.getNetworkType(GameCenterActivity.this).equals(NetworkType.WIFI)) {
                LogUtil.d(TAG, "onReceive()---网络切换/WIFI可用->");
                if (mIsHomePage) {
                    removeBackgroundMessages(MSG_BACK_CONTINUE_ABNORMAL_DOWNLOAD_TASK);
                    sendEmptyBackgroundMessageDelayed(MSG_BACK_CONTINUE_ABNORMAL_DOWNLOAD_TASK,
                            2000);
                }
            }
        } else if (SDKActions.ACTION_LOGIN_SUCCESS.equals(action)) {// 登录成功
            if (mProvider != null) {
                mWeb.loadUrl("javascript:invokeLoginCallBack('" + getSource() + "','"
                        + mProvider.getUserInfo() + "')");
                LogUtil.d(TAG, "onReceive()---登录成功:source-->" + getSource() + "--userinfo-->"
                        + mProvider.getUserInfo());
            }

        } else if (SDKActions.ACTION_REGISTER_SUCCESS.equals(action)) {// 激活账号（注册）成功
            if (mProvider != null) {
                mWeb.loadUrl("javascript:invokeRegisterCallBack('" + getSource() + "','"
                        + mProvider.getUserInfo() + "')");
                LogUtil.d(TAG, "onReceive()---注册成功:source-->" + getSource() + "--userinfo-->"
                        + mProvider.getUserInfo());
            }
        }
    }

    /**
     * 重新下载由用户开启但不是被用户主动暂停中断的任务
     */
    private synchronized void continueAbnormalPauseDownloadTasks() {
        ArrayList<DownloadFile> cacheFiles = DownloadServiceUtil.getDownloadFilesFromCache();
        if (cacheFiles != null) {
            for (DownloadFile file : cacheFiles) {
                if (file != null && file.getState() != FileDownloader.FINISH) {
                    String flag = file.getExt9();
                    if (!TextUtils.isEmpty(flag) && flag.equals("1")) {
                        LogUtil.d("111", "--------------continueAbnormalPauseDownload()---开启继续下载->"
                                + file.getFileName());
                        ParamsWrapper params = DownloadHelper
                                .getParamsWrapperFromDownloadFile(file);
                        DownloadHelper.download(params, null);
                    }
                }
            }
        }
    }

    public synchronized void stopDownload(String filehash) {
        DownloadFile file = DownloadServiceUtil.getDownloadFileFromCache(filehash);
        if (file != null) {
            LogUtil.d("111", "stopDownload()--->" + file.getFileName());
        }
        // 将该filehash对应的应用状态标记为不需要自动下载
        DownloadHelper.setAppAutoDownloadFlag(filehash, 0);
        DownloadHelper.stopDownload(filehash);
    }

    public boolean isActivityDestroy() {
        return mIsDestroy;
    }

    public String getSource() {
        return mSource;
    }

    public void setSource(String source) {
        this.mSource = source;
    }
}
